package com.FH.util;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.*;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

public class ExportPDF {

	public static String createPDFFile(List<String[]> dataset,String title,String[] headers,String filename) throws DocumentException{
		String downloadUrl = "";
		try {
			String outFilePath = "";
			String downLoadPath = "";

			String unloadPath = "";

			//获取当前工程目录
			File f = new File(System.getProperty("user.dir"));

			//获取操作系统类型
			String os = System.getProperty("os.name");

			//判断操作系统类型
			if(os.toLowerCase().startsWith("win")){
				//excel在服务器中所在路径
				downLoadPath = "/download/PDF/";
				unloadPath = f.getParent().replaceAll("\\\\","/") + "/welcome-content" + downLoadPath;
			}
			else{
				//excel在服务器中所在路径
				downLoadPath = "/download/PDF/";
				unloadPath = f.getParent() + "/welcome-content" + downLoadPath;
			}


			File dirFile = new File(unloadPath);
			//如果dir对应的文件不存在，或者不是一个目录，则退出
			if (!dirFile.exists() || !dirFile.isDirectory()) {
				dirFile.mkdirs();
			}

			outFilePath = unloadPath + filename + ".pdf";

			//输出文档路径及名称
			File outFile = new File(outFilePath);
			if (!outFile.exists()) {
				outFile.createNewFile();
			}

			//构造输出流输出文档
			OutputStream out = new FileOutputStream(outFile);
			String str = outFile.getName();
			testRowSpan(outFilePath,dataset,title,headers);
//	            out.close();
			System.out.println("pdf导出成功！");

			downloadUrl = downLoadPath + filename + ".pdf";
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return downloadUrl;
	}

	private static void testRowSpan(String fileName,List<String[]> list,String title,String[] headers)
			throws IOException, DocumentException {
		BaseFont bfCN = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false);

		Font fontTitle = new Font(bfCN, 12.0F, Font.BOLD,BaseColor.BLACK);

		// 正文的字体
		Font headFont = new Font(bfCN, 10f, Font.NORMAL, BaseColor.BLACK);
		Font textFont = new Font(bfCN, 9f, Font.NORMAL, BaseColor.BLACK);

		Document document = new Document(PageSize.A4.rotate());
		PdfWriter.getInstance(document, new FileOutputStream(fileName));
		document.open();

		document.add(new Paragraph(new Chunk(title, fontTitle).setLocalDestination(title)));
		document.add(new Paragraph("\n"));

		//建立一个4列的表格
		PdfPTable table = new PdfPTable(headers.length);

		//计算'合并列'的合并相关集合
		List<Integer> indexs;
		//每个'合并列'的初始下标集合
		List<Integer> spanStartIndex;
		//每个'合并列'的合并数量集合
		List<Integer> spanNumList;
		//取出'合并列'的所有数据计算
		List<String> ListIn = new ArrayList<>();
		for (String[] aList : list) {
			ListIn.add(aList[1]);
		}
		spanNumList = getSpanNumList(ListIn);
		spanStartIndex = getStartIndexList(ListIn, spanNumList);
		indexs = getIndexs(list, spanNumList, spanStartIndex);

		//加表格头部
//	        String[] titleArr = {"第1列", "合并列", "第3列", "第4列"};
		addTitle(table, headers, headFont);

		//加表格内容
		addContent(table, list, textFont, spanNumList, spanStartIndex, indexs,headers.length,title);

		table.setHeaderRows(1);

		document.add(table);
		document.close();
	}

	private static void addContent(PdfPTable table, List<String[]> list, Font textFont,
								   List<Integer> spanNumList, List<Integer> spanStartIndex, List<Integer> indexs,int headerlength,String title) {
		//表格数据内容
		for (int i = 0; i < list.size(); i++) {

			String[] str = list.get(i);

			for(int j=1;j<=headerlength;j++){
				Paragraph paragraph01 = new Paragraph(str[j], textFont);
				paragraph01.setAlignment(1);
				PdfPCell cell = new PdfPCell();
				cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
				cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//然并卵
//				cell.setPaddingTop(-2f);//把字垂直居中
//				cell.setPaddingBottom(8f);//把字垂直居中
                cell.setUseAscender(true);//把字垂直居中
                cell.setVerticalAlignment(cell.ALIGN_MIDDLE);//把字垂直居中
				cell.addElement(paragraph01);
				if(j == 1){
//					if(title.equals("部门周计划")){

						setRowsSpan(indexs, spanStartIndex, spanNumList, table, cell, i);

//					}
//					else {
//						table.addCell(cell);
//					}

				}else{
					table.addCell(cell);
				}
			}
		}
	}

	/**
	 * 设置恰当位置的setRowSpan属性
	 * @param indexs            不加单元格的索引集合
	 * @param spanStartIndex    要加的单元格开始索引集合
	 * @param spanNumList       要加的单元格合并的值集合
	 * @param table             table
	 * @param cell              cell
	 * @param i                 索引
	 */
	private static void setRowsSpan(List<Integer> indexs, List<Integer> spanStartIndex,
									List<Integer> spanNumList, PdfPTable table, PdfPCell cell, int i) {
		if (indexs != null) {
			Boolean isAllNotEqual = true;
			for (Integer index : indexs) {
				if (i == index) {
					isAllNotEqual = false;
				}
			}

			//没有不加的下标
			if (isAllNotEqual) {
				//判断在哪里设置span值
				if (spanStartIndex != null) {
					Boolean isSpan = false;
					int copyJ = 0;
					for (int j = 0; j < spanStartIndex.size(); j++) {
						if (i == spanStartIndex.get(j)) {
							isSpan = true;
							copyJ = j;
							break;
						}
					}
					if (isSpan) {
						int spanNum = spanNumList.get(copyJ);
						cell.setRowspan(spanNum);
					}
				}
				table.addCell(cell);
			}
		} else {
			table.addCell(cell);
		}
	}

	private static void addTitle(PdfPTable table, String[] titleArr, Font headFont) {
		for (String aTitleArr : titleArr) {
			Paragraph p = new Paragraph(aTitleArr, headFont);
			PdfPCell cell = new PdfPCell();
			p.setAlignment(1);
			cell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
			cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//然并卵
//			cell.setPaddingTop(-2f);//把字垂直居中
//			cell.setPaddingBottom(8f);//把字垂直居中
			cell.setUseAscender(true);//把字垂直居中
			cell.setVerticalAlignment(cell.ALIGN_MIDDLE);//把字垂直居中
			cell.addElement(p);
			table.addCell(cell);
		}
	}

	/**
	 * 获取某列要合并的单元格数量
	 * @param list 内容必须符合'A,A,B,C,D,D,D,E' 而不是 'A,A,B,C,A,D,D,D,E' ，即所有相同的值必须在一起不能分散
	 * @return
	 */
	private static List<Integer> getSpanNumList(List<String> list) {

		LinkedHashMap<String,Integer> map = new LinkedHashMap <>();
		if(list.size() > 0) {
			for (int i = 0; i < list.size(); i = i + 1) {
				map.put(list.get(i), i);
			}
		}

		//修改对应key值的value
		Set<String> s = map.keySet();//获取KEY集合
		List<String> strings = new ArrayList<>(s);
		int spanNum = 0;
		for (String string : strings) {
			int tmpSpanNum = map.get(string) - spanNum + 1;
			map.put(string, tmpSpanNum);
			spanNum += tmpSpanNum;
		}

		List<Integer> res = new ArrayList<>();
		for (String string : strings) {
			res.add(map.get(string));
		}
		return res;
	}

	/**
	 * 获取某列要合并的单元格初始下标
	 * @param list              内容必须符合'A,A,B,C,D,D,D,E' 而不是 'A,A,B,C,A,D,D,D,E' ，即所有相同的值必须在一起不能分散
	 * @param resSpanNumList
	 * @return
	 */
	private static List<Integer> getStartIndexList(List<String> list, List<Integer> resSpanNumList) {

		LinkedHashMap <String,Integer> map = new LinkedHashMap <>();
		if(list.size() > 0) {
			for (int i = 0; i < list.size(); i = i + 1) {
				map.put(list.get(i), i);
			}
		}

		Set<String> keys = map.keySet();//获取KEY集合
		List<String> stringKeys = new ArrayList<>(keys);

		List<Integer> res = new ArrayList<>();
		if (stringKeys.size() == resSpanNumList.size()) {
			for(int i = 0; i < stringKeys.size(); i++){
				res.add(map.get(stringKeys.get(i)) - resSpanNumList.get(i) + 1);
			}
		}
		return res;
	}

	/**
	 * 不加某字段的索引集合
	 * @param list
	 * @param resSpanNumList
	 * @param resStartIndexList
	 * @return
	 */
	private static List<Integer> getIndexs(List<String[]> list,
										   List<Integer> resSpanNumList, List<Integer> resStartIndexList) {
		List<Integer> indexs = new ArrayList<>();
		for (int i = 0; i < list.size(); i++) {
			for (int j = 0; j < resStartIndexList.size(); j++) {
				if (i == resStartIndexList.get(j)) {
					for (int k = i + 1; k < i + resSpanNumList.get(j); k++) {
						indexs.add(k);
					}
				}
			}
		}
		return indexs;
	}
}
